package evemanutool.utils.datahandling;
import java.util.concurrent.LinkedBlockingQueue;
import evemanutool.gui.general.components.AnimatedLabel;
public class MessageHandler extends ThreadedHandler {
//Constants.
private static final long TICK = 5;
private static final int MIN_TICKS = 300; // 1 s.
private static final int MAX_TICKS = 1000; // 5 s.
//Message queue.
private LinkedBlockingQueue<String> queue = new LinkedBlockingQueue<>();
//Worker thread.
private Thread worker;
//GUI.
private AnimatedLabel label;
//Object locks.
private final Object labelLock = new Object();
public MessageHandler() {}
public AnimatedLabel getLabel() {
synchronized (labelLock) {
return label;
}
}
public void setLabel(AnimatedLabel label) {
synchronized (labelLock) {
this.label = label;
//Make sure that it's not showing the text.
this.label.setTextShowing(false);
}
}
public void addMessage(String message) {
queue.offer(message);
System.out.println("Message: " + message);
}
@Override
public void init() {
if (!isRunning()) {
setRunning(true);
//Start worker.
worker = new Thread(new MessageWorker());
worker.start();
}
}
@Override
public void exit() {
if (isRunning()) {
getLabel().exit();
worker.interrupt();
}
}
@Override
public void kill() {
exit();
}
private class MessageWorker implements Runnable {
@Override
public void run() {
while (!Thread.interrupted()) {
try {
//Get message from queue (blocking).
//Set text and start animation.
getLabel().setText(queue.take());
getLabel().animateIn();
//Wait for animation to complete.
while (!getLabel().textShowing()) {
Thread.sleep(TICK);
}
//Depending if there are more messages to show:
//Let the message show for a while.
for (int i = 0; i < MAX_TICKS ; i++) {
if (!queue.isEmpty() && i > MIN_TICKS) {
break;
}
Thread.sleep(TICK);
}
//Animate out and wait for completion.
getLabel().animateOut();
while (getLabel().textShowing()) {
Thread.sleep(TICK);
}
} catch (InterruptedException e) {
//End thread.
return;
}
}
}
}
}